<script lang="ts" setup>
import { ICodeRow } from '@preload/types';
import { NumberEditor } from '@renderer/components/J-Table/NumberEditor';
import { useStore } from '@renderer/Store';
import { data } from '@visactor/vtable';
import { InputEditor } from '@visactor/vtable-editors';
import type { StylePropertyFunctionArg } from '@visactor/vtable/es/ts-types';
import { ListColumn, ListTable, register, VTable } from '@visactor/vue-vtable';

const listTableRef = ref();
const store = useStore();
const headerStyle = {
  fontSize: 12
};
// 单元格样式函数
const style = {
  fontSize() {
    return 12;
  },
  bgColor(styleArg: StylePropertyFunctionArg) {
    const codeTable = store.codeTable.value;
    if (codeTable) {
      // 首行是标题行，因此需要减1
      const rowIndex = styleArg.row - 1;
      const row = codeTable.data.codeRows[rowIndex];
      // 判断是否需要特殊背景色
      if (row.originalSeparator !== codeTable.separator) {
        return 'lightgreen';
      }
    }
    return '';
  }
};
// 编辑器注册
const inputEditor = new InputEditor();
const numberEditor = new NumberEditor();
register.editor('inputEditor', inputEditor);
register.editor('numberEditor', numberEditor);

const options = {
  defaultHeaderRowHeight: 30, // 设置表头默认行高
  defaultRowHeight: 30,       // 设置表格默认行高
  editCellTrigger: [
    'doubleclick',
    'keydown'
  ],
  heightMode: 'standard',     // 使用标准模式计算行高
  widthMode: 'auto'
};


function lazyLoading(codeRows: ICodeRow[]) {
  // 分页配置
  const pageSize = 5; // 每页记录数

  // 创建分页缓存容器，使用Map存储已加载的批次数据
  // 键：页码索引，值：异步获取数据的Promise对象
  const loadedBatches = new Map<number, Promise<ICodeRow[]>>();

  // 更新数据源
  getTableInstance().dataSource = new data.CachedDataSource({
    // 核心异步数据加载方法
    get: async (currentIndex: number) => {
      // 根据当前索引计算页码和当前页起始索引
      const pageIndex = Math.floor(currentIndex / pageSize);
      const startIndex = pageIndex * pageSize;

      // 缓存策略实现
      if (!loadedBatches.has(pageIndex)) {
        // 模拟异步加载流程
        loadedBatches.set(pageIndex, Promise.resolve(codeRows.slice(startIndex, startIndex + pageSize)));
      }

      // 获取已缓存数据
      const batchData = await loadedBatches.get(pageIndex)!;
      return batchData[currentIndex - startIndex]; // 计算当前页内的偏移索引
    },
    length: codeRows.length // 保持与实际数据总长度一致
  });
}


watch(() => store.codeTable.value, codeTable => {
  if (!codeTable) {
    return;
  }
  lazyLoading(codeTable.data.codeRows);
});

const onChangeCellValue = ({ row }) => {
  const codeRowIndex = row - 1; // 首行是标题行
  if (codeRows) {
    const codeRowLength = codeRows.value.length;
    // 索引边界检查
    if (codeRowIndex < 0 || codeRowIndex > codeRowLength) {
      throw new Error(`索引越界：${codeRowIndex}，码表词条总长：${codeRowLength}`);
    }

    const codeRow = codeRows[codeRowIndex];
    // 数据同步检查
    if (codeRow) {
      store.codeTable.value!.changedCodeRowSet.add(codeRow);
    }
  }
};
const codeRows = computed(() => {
  if (store.codeTable.value) {
    return store.codeTable.value.data.codeRows;
  }
  return [];
});

const getTableInstance = () => {
  return (listTableRef.value!.vTableInstance as VTable.ListTable);
};

// 参数为 event: TableEventHandlersEventArgumentMap['checkbox_state_change']
const onCheckboxStateChange = () => {
  store.codeTable.value!.selectedLength = getTableInstance().getCheckboxState('lineIndex').filter(item => item).length;
};
</script>

<template>
  <div class="table-container">
    <ListTable ref="listTableRef" :headerStyle="headerStyle" :options="options" :records="codeRows"
      @onChangeCellValue="onChangeCellValue" @onCheckboxStateChange="onCheckboxStateChange">
      <ListColumn :headerStyle="headerStyle" :style="style" cellType="checkbox" field="lineIndex" title="行号"
        width="100" />
      <ListColumn :headerStyle="headerStyle" :sort='true' :style="style" editor="inputEditor" field="text" title="词"
        width="200" />
      <ListColumn :headerStyle="headerStyle" :sort='true' :style="style" editor="inputEditor" field="code" title="编码"
        width="250" />
      <ListColumn :headerStyle="headerStyle" :sort='true' :style="style" editor="numberEditor" field="weight" title="权重"
        width="80" />
      <ListColumn :headerStyle="headerStyle" :sort='true' :style="style" editor="inputEditor" field="stem" title="造词码"
        width="250" />
    </ListTable>
  </div>
</template>

<style scoped>
.table-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding-bottom: 5px;
}

.table {
  flex: 1;
  overflow: auto;
  border: 1px solid #f0f0f0;
  border-radius: 2px;
}
</style>